home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 14343 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  3.8 KB

  1. Path: nntp.irvine.com!adam
  2. From: adam@irvine.com (Adam Beneschan)
  3. Newsgroups: comp.lang.ada,comp.lang.c++
  4. Subject: Re: some questions re. Ada/GNAT from a C++/GCC user
  5. Date: 29 Mar 1996 23:52:59 GMT
  6. Organization: /z/news/newsctl/organization
  7. Message-ID: <4jht4r$tpo@krusty.irvine.com>
  8. References: <wnewmanDoxrCp.DKv@netcom.com> <315AC5E7.3A77@escmail.orl.mmc.com>
  9. NNTP-Posting-Host: calvin.irvine.com
  10.  
  11. Ted Dennison <dennison@escmail.orl.mmc.com> writes:
  12.  
  13.  >> When I make two different instantiations of a generic package with the
  14.  >> same arguments, I understand the compiler treats them formally as two
  15.  >> different packages, which is OK with me.  However, I'd appreciate
  16.  >> knowing the compiler wouldn't actually output two redundant copies of
  17.  >> the corresponding (identical?) machine code, but instead share the
  18.  >> code.  I saw somewhere that the compiler is given considerable freedom
  19.  >> to share one instantiation between several arguments if it thinks it's
  20.  >> appropriate, which is also OK with me.  However, I haven't seen any
  21.  >> guarantee that the compiler won't output redundant copies for
  22.  >> instantiations with identical arguments.  Is there such a guarantee?
  23.  >
  24.  >If you want a guarantee, put the code you want shared in a non-generic
  25.  >package or procedure, and call it from your generic package or
  26.  >procedure.
  27.  
  28. I don't think this will always work, at least not cleanly.  Suppose
  29. you have a generic whose only generic formal parameter is a private
  30. type:
  31.         
  32.         generic
  33.             type T is private;
  34.         package GENERIC_PACKAGE is
  35.             ... 
  36.             procedure Do_Something (X : out T);
  37.             procedure Do_Something_Else (X : in T);
  38.             ...
  39.         end GENERIC_PACKAGE;
  40.  
  41. About the only thing the generic package body can do with objects of
  42. type T is to move them around.  So, ignoring for the moment strange
  43. cases like unconstrained arrays, it should be easy for a compiler to
  44. generate one copy of Do_Something and Do_Something_Else (and similarly
  45. any procedure declared in the package body) for all instantiations of
  46. GENERIC_PACKAGE.  Each procedure would take the size of T as an extra
  47. parameter, and whenever the procedure needs to move objects of type T
  48. around, it just does a raw byte copy, using the size parameter.  This
  49. should run only slightly slower than if the compiler generated a
  50. separate copy of Do_Something for every instantiation, and each copy
  51. were able to treat the size as a known constant.
  52.  
  53. But suppose you have a compiler that always generates a separate copy
  54. of all procedures for each instantiation.  How would you write a
  55. non-generic shared procedure that you could call from the generic
  56. package? 
  57.  
  58.     procedure Non_Generic_Do_Something (---well, what?)
  59.  
  60. What types would the parameters of this routine be?  The only
  61. possibilities I can see would be to have this routine take a
  62. SYSTEM.ADDRESS and a size parameter, or a byte array type, or some
  63. other low-level type.  No matter how you do it, the code in
  64. GENERIC_PACKAGE, in order to call Non_Generic_Do_Something, would have
  65. to use UNCHECKED_CONVERSION or something like that (which doesn't fit
  66. my definition of "cleanly").
  67.  
  68. Even if all you want is to make sure that only one copy of the code
  69. is generated when the generic parameters are identical, how can you do
  70. this by writing a shared non-generic routine?  If, in four different
  71. places, you say:
  72.  
  73.     package GP1 is new GENERIC_PACKAGE (RECORD_TYPE_1);
  74.  
  75.     package GP2 is new GENERIC_PACKAGE (RECORD_TYPE_2);
  76.  
  77.     package GP3 is new GENERIC_PACKAGE (RECORD_TYPE_1);
  78.  
  79.     package GP4 is new GENERIC_PACKAGE (RECORD_TYPE_2);
  80.  
  81. How could you write the Non_Generic_Do_Something routine, and the
  82. generic Do_Something procedure, so that just two versions of the
  83. Do_Something code (one to handle RECORD_TYPE_1 and one to handle
  84. RECORD_TYPE_2) are generated by the compiler?
  85.  
  86.                                 -- Adam
  87.